#include "view.h"
#include "display_ctrl.h"
#include "view_abstract.h"
#include "platform_assert.h"
#include "time/view_times.h"
#include "heart_rate/view_heart_rate.h"
#include "calories/view_calories.h"
#include "steps/view_steps.h"
#include "others/view_others.h"
#include "metronome/view_metronome.h"
#include "outdoors/view_outdoors.h"
#include "sports/view_sports.h"
#include "relax/view_relax.h"
#include "music/view_music.h"
#include "app_trace.h"
#include "view_prompt.h"
#include "view_system.h"
#include "sports_mode.h"
#include "m_product_test.h"
#include "prj_typedef.h"
#define LOG(fmt, ...) app_trace_log(fmt "\r\n", ##__VA_ARGS__)
typedef struct __view_level_0_t
{
    abstract_view_display display;
    abstract_view_event event;
} view_level_0_t;

view_level_0_t const view_level_0_interface[] = {
    {view_time_display, view_time_event},           {view_heart_rate_display, view_heart_rate_event}, {view_steps_display, view_steps_event}, {view_calories_display, view_calories_event},
    {view_others_display, view_others_event},
#ifdef NO_OUTDOORS_UI
#else
    {view_outdoors_display, view_outdoors_event},
#endif
    {view_metronome_display, view_metronome_event}, {view_relax_display, view_relax_event},           {view_music_display, view_music_event}, {view_sports_display, view_sports_event},

};

view_level_0_t const *get_level_0_interface(int32_t view)
{
    if (view < view_start || view >= view_end)
    {
        return 0;
    }
    int view_index = (view - view_start) / VIEW_LEVEL_0_SUB_COUNT;
    if (view_index >= sizeof(view_level_0_interface) / sizeof(view_level_0_interface[0]))
    {
        Ensures(0);
        return 0;
    }
    return &view_level_0_interface[view_index];
}

/**
 * @brief
 *
 * @param view
 * @param level_index 当前级数的第几个页面
 * @return view_level_t 几级页面
 */
view_level_t get_view_level(int32_t view, int *p_level_index)
{
    int remainder = view - view_start; //!< 余数
    int quotient = 0;                  //!< 商
    quotient = remainder / VIEW_LEVEL_0_SUB_COUNT;
    remainder = remainder % VIEW_LEVEL_0_SUB_COUNT;
    if (remainder == 0)
    {
        if (p_level_index != 0)
        {
            *p_level_index = quotient;
        }
        return view_level_0;
    }
    quotient = remainder / VIEW_LEVEL_1_SUB_COUNT;
    remainder = remainder % VIEW_LEVEL_1_SUB_COUNT;
    if (remainder == 0)
    {
        if (p_level_index != 0)
        {
            *p_level_index = quotient;
        }
        return view_level_1;
    }
    quotient = remainder / VIEW_LEVEL_2_SUB_COUNT;
    remainder = remainder % VIEW_LEVEL_2_SUB_COUNT;
    if (p_level_index != 0)
    {
        *p_level_index = quotient;
    }
    //!< 三级页面
    return view_level_2;
}
/**
 * @brief 同级切换,上一个页面
 *
 * @param view
 */
void level_0_move_previous_view(int32_t view)
{
    int level_index = 0;
    view_level_t view_level = get_view_level(view, &level_index);
    int32_t new_view = 0;
    disp_mode_t disp_mode = DISP_MODE_NORMAL;
    if (level_index == 1 && view_level != view_level_0)
    {
        return;
    }
    if (level_index == 0 && view_level == view_level_0)
    {
        new_view = view_end - VIEW_LEVEL_0_SUB_COUNT;
        disp_mode = DISP_MODE_UP_MOVE;
    }
    else
    {
        switch (view_level)
        {
        case view_level_0:
            disp_mode = DISP_MODE_UP_MOVE;
            new_view = view - VIEW_LEVEL_0_SUB_COUNT;
            break;
        case view_level_1:
            disp_mode = DISP_MODE_UP_MOVE;
            new_view = view - VIEW_LEVEL_1_SUB_COUNT;
            break;
        case view_level_2:
            disp_mode = DISP_MODE_UP_MOVE;
            new_view = view - VIEW_LEVEL_2_SUB_COUNT;
            break;
        }
    }
    LOG("view[%d] level[%d] previous view[%d] ", view, view_level, new_view);
    display_show(new_view, disp_mode);
}

/**
 * @brief 同级切换，下一个页面
 *
 * @param view
 */
void level_0_move_next_view(int32_t view)
{
    int level_index = 0;
    view_level_t view_level = get_view_level(view, &level_index);
    int32_t new_view = 0;
    disp_mode_t disp_mode = DISP_MODE_NORMAL;
    view_level_t new_view_level = view_level_0;
    switch (view_level)
    {
    case view_level_0:
        disp_mode = DISP_MODE_DOWN_MOVE;
        new_view = view + VIEW_LEVEL_0_SUB_COUNT;
        if (new_view == view_end)
        {
            new_view = view_start;
        }
        break;
    case view_level_1:
        disp_mode = DISP_MODE_DOWN_MOVE;
        new_view = view + VIEW_LEVEL_1_SUB_COUNT;
        new_view_level = get_view_level(new_view, 0);
        if (new_view_level != view_level)
        {
            return;
        }
        break;
    case view_level_2:
        disp_mode = DISP_MODE_DOWN_MOVE;
        new_view = view + VIEW_LEVEL_2_SUB_COUNT;
        new_view_level = get_view_level(new_view, 0);
        if (new_view_level != view_level)
        {
            return;
        }
        break;
    }
    LOG("view[%d] level[%d] next_view view[%d] ", view, view_level, new_view);
    display_show(new_view, disp_mode);
}
/**
 * @brief 右边的下一页
 *
 * @param view
 */
void level_0_level_down(int32_t view)
{
    view_level_t view_level = get_view_level(view, 0);
    int32_t new_view = 0;
    switch (view_level)
    {
    case view_level_0:
        new_view = view + VIEW_LEVEL_1_SUB_COUNT;
        break;
    case view_level_1:
        new_view = view + VIEW_LEVEL_2_SUB_COUNT;
        break;
    case view_level_2:
        return;
    }
    LOG("view[%d] level[%d] entry view[%d] ", view, view_level, new_view);
    display_show(new_view, DISP_MODE_NORMAL);
}
/**
 * @brief 1级页面回首页，其他页面回一级页面
 *
 * @param view
 */
void level_0_level_up(int32_t view)
{
    int level_index = 0;
    view_level_t view_level = get_view_level(view, &level_index);
    int32_t new_view = 0;
    switch (view_level)
    {
    case view_level_0:
        // new_view = view - level_index * VIEW_LEVEL_0_SUB_COUNT;
        new_view = view_time;
        break;
    case view_level_1:
        new_view = view - level_index * VIEW_LEVEL_1_SUB_COUNT;
        break;
    case view_level_2:
        new_view = view - level_index * VIEW_LEVEL_2_SUB_COUNT;
        break;
    }
    LOG("view[%d] level[%d] back view[%d] ", view, view_level, new_view);
    display_show(new_view, DISP_MODE_NORMAL);
}
void event_previous_view_broadcast(void)
{
    event_param_t param = {
        .source = event_source_system,
        .event = event_move_previous_view,
    };
    view_event(param);
}
void event_next_view_broadcast(void)
{
    event_param_t param = {
        .source = event_source_system,
        .event = event_move_next_view,
    };
    view_event(param);
}
void event_level_up_broadcast(void)
{
    event_param_t param = {
        .source = event_source_system,
        .event = event_move_level_up,
    };
    view_event(param);
}
void event_level_down_broadcast(void)
{
    event_param_t param = {
        .source = event_source_system,
        .event = event_move_level_down,
    };
    view_event(param);
}
void event_transition(event_param_t param)
{
    switch (param.source)
    {
#ifdef PROJECT_X3_E
    case event_source_button_x3_e_top:
    {
        switch (param.event)
        {
        case BUTTON_EVENT_SHORT_PRESS:
            event_level_up_broadcast();
            break;
        case BUTTON_EVENT_LONG_PRESS:
            if (DeviceState.PowerState == POWEROFFOK)
            {
                view_power_on_event(param);
            }
            else
            {
                product_test_state_t state = product_test_state_get();
                switch (state)
                {
                case PRODUCT_TEST_STATE_TEST_NONE:
                    break;
                case PRODUCT_TEST_STATE_TEST_PCBA:
                    break;
                case PRODUCT_TEST_STATE_TEST_ASSEM:
                    motor_start(500);
                    system_into_poweroff();
                    break;
                }
                break;
            }
            break;
        }
        break;
    }
    case event_source_button_x3_e_bottom:
    {
        switch (param.event)
        {
        case BUTTON_EVENT_SHORT_PRESS:
            if (display_get_present_type() == view_time)
            {
                display_show(view_sports_level_1_begin, DISP_MODE_DOWN_MOVE);
            }
            else
            {
                event_level_up_broadcast();
            }
            break;
        }
        break;
    }
#endif
// #ifdef EVENT_BUTTON_SPORT
//     case event_source_button_sport:
//     {
//         switch (param.event)
//         {
//         case BUTTON_EVENT_SHORT_PRESS:
//             if (display_get_present_type() != view_time || disp_ctrl.on == DISP_ON_DISABLE)
//             {
//                 display_show(view_time, DISP_MODE_NORMAL);
//             }
//             else
//             {
//                 disp_ctrl.auto_close_delay = 1;
//             }
//             break;
//         }
//     }
// #endif
#if defined(BUTTON_TOP)
    case event_source_button_top:
        event_previous_view_broadcast();
        break;
#endif
#if defined(BUTTON_MIDDLE)
    case event_source_button_middle:
    {
        switch (param.event)
        {
        case BUTTON_EVENT_SHORT_PRESS:
            event_level_down_broadcast();
            break;
        case BUTTON_EVENT_LONG_PRESS:
            event_level_up_broadcast();
            break;
        }
    }
    break;
#endif
#if defined(BUTTON_BOTTOM)
    case event_source_button_bottom:
        event_next_view_broadcast();
        break;
#endif
    case event_source_touch:
    {
        switch (param.event)
        {
        case BUTTON_EVENT_TP_TAP:
            event_level_down_broadcast();
            break;
        case BUTTON_EVENT_TP_MOVE_UP:
            event_next_view_broadcast();
            break;
        case BUTTON_EVENT_TP_MOVE_DOWN:
            event_previous_view_broadcast();
            break;
        case BUTTON_EVENT_TP_MOVE_LEFT:
            event_level_down_broadcast();
            break;
        case BUTTON_EVENT_TP_MOVE_RIGHT:
            event_level_up_broadcast();
            break;
        default:
            break;
        }
    }
    break;

    default:
        break;
    }
}

bool level_0_event_handle(int32_t view, event_param_t param)
{
    if (view < view_start || view >= view_end)
    {
        return false;
    }
    view_level_0_t const *level_0 = get_level_0_interface(view);
    if (level_0 == 0)
    {
        return false;
    }
    view_event_result_t result = level_0->event(view, param);
    if (result == view_event_result_handled)
    {
        return true;
    }
    if (param.source == event_source_system)
    {
        switch (param.event)
        {
        case event_move_previous_view:
            level_0_move_previous_view(view);
            return true;

        case event_move_next_view:
            level_0_move_next_view(view);
            return true;

        case event_move_level_up:
            level_0_level_up(view);
            return true;

        case event_move_level_down:
            level_0_level_down(view);
            return true;

        default:
            return false;
        }
    }
    return false;
}
void view_event(event_param_t param)
{
    int32_t view = disp_ctrl.current_disp_type;
    if (DeviceState.PowerState == POWEROFFOK && param.event != event_view_exit)
    {
        view_power_on_event(param);
        view_power_off_charing_event(param);
        return;
    }

    if (disp_ctrl.on == DISP_ON_DISABLE)
    {
        switch (param.event)
        {
        case BUTTON_EVENT_SHORT_PRESS:
        case BUTTON_EVENT_LONG_PRESS:
        case BUTTON_EVENT_LONG_PRESS_KEEP:
            //!< 已灭屏，要把屏点亮
            LOG("put screen power on");
            if (view == view_close_oled)
            {
                view = view_empty;
            }
            display_show(view, DISP_MODE_NORMAL);
            return;
        }
    }
    switch (param.event)
    {
    case BUTTON_EVENT_TP_TAP:
    case BUTTON_EVENT_SHORT_PRESS:
    case BUTTON_EVENT_LONG_PRESS:
    case BUTTON_EVENT_LONG_PRESS_KEEP:
    case BUTTON_EVENT_TP_MOVE_UP:
    case BUTTON_EVENT_TP_MOVE_DOWN:
    case BUTTON_EVENT_TP_MOVE_LEFT:
    case BUTTON_EVENT_TP_MOVE_RIGHT:
        if (disp_ctrl.auto_close_delay < DISP_CLOSE_TIME_DEFAULT)
        {
            LOG("close delay restore by key");
            disp_ctrl.auto_close_delay = DISP_CLOSE_TIME_DEFAULT;
        }
        break;
    }
    if (finished_product_event(view, param) == view_event_result_handled)
    {
        return;
    }
    if (level_0_event_handle(view, param))
    {
        return;
    }
    if (view_prompt_event(view, param))
    {
        return;
    }
    if (view_system_event(view, param))
    {
        return;
    }
    event_transition(param);
}
void view_display(void)
{
    // oled_turn_on();
    int32_t view = disp_ctrl.current_disp_type;
    if (finished_product_display(view))
    {
        return;
    }
    view_level_0_t const *level_0 = get_level_0_interface(view);
    if (level_0 != 0)
    {
        level_0->display(view);
        return;
    }
    if (view_prompt_display(view))
    {
        return;
    }
    if (view_system_display(view))
    {
        return;
    }
}
bool is_view_exit_to_empty(int view)
{
    switch (disp_ctrl.current_disp_type)
    {
    case view_relax_animation:
    case view_others_stopwatch_state:
    case view_metronome_state:
    case view_metronome_option:
        // case view_sports_result_0:
        // case view_sports_result_1:
#ifdef NO_OUTDOORS_UI
#else
    case view_outdoors_altitude:
    case view_outdoors_altitude_options:
    case view_outdoors_altitude_set_0:
    case view_outdoors_altitude_set_1:
    case view_outdoors_temperature:
    case view_outdoors_pressure:
#ifdef USE_GEOMAGNETISM
    case view_outdoors_geomagnetism:
#endif
#endif
    case view_others_camera:
    case view_others_camera_static:
    case view_others_camera_shake:
    case view_others_stopwatch:
    case view_others_device_info:
    case view_others_device_info_detail:
    case view_others_app_url:
    case view_others_power_off:
    case view_others_power_off_confirm:
    case view_music_state:
        return false;
    default:
        if (sports_mode_get_state() == sports_mode_state_idle)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}
/*********************************************************************************************
 * @brief 查询当前界面优先级
 * @warning
 ********************************************************************************************/
disp_type_priority_t display_get_present_type_priority(void)
{
    disp_type_t current_ui = display_get_present_type();
    if (current_ui == view_empty) //空闲
    {
        return DISP_TYPE_PRIORITY_STANDBY;
    }
    switch (current_ui)
    {
    case view_others_stopwatch:
    case view_others_stopwatch_state:
    case view_power_off_animation:
    case view_power_on_animation:
    case view_metronome_state:
    case view_relax_animation:
    case view_relax_tips:
        return DISP_TYPE_PRIORITY_SYSTEM;
    case view_prompt_alarm:
        return DISP_TYPE_PRIORITY_ALARM;
    case view_heart_rate_test:
        return DISP_TYPE_PRIORITY_APP_MEASURE;
    case view_heart_rate_result:
        return DISP_TYPE_PRIORITY_ALERT;
    case view_others_camera_static:
    case view_others_camera_shake:
        return DISP_TYPE_PRIORITY_APP_MEASURE;
    case view_prompt_message:
        return DISP_TYPE_PRIORITY_ALARM;
    }
    if (current_ui >= view_prompt_start && current_ui < view_prompt_priority_alert_end) //提醒类界面
    {
        return DISP_TYPE_PRIORITY_ALERT;
    }
    return DISP_TYPE_PRIORITY_NORMAL;
}
